package jermedit.gui;

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.PointerInfo;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.util.Iterator;
import java.util.LinkedList;
import javax.swing.JComboBox;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import jermedit.gobjekte.BaseType;
import jermedit.gobjekte.EditPoint;
import jermedit.gobjekte.EnumType;
import jermedit.gobjekte.LineObject;
import jermedit.gobjekte.RepresentedBy;
import jermedit.gobjekte.DerivationNod;
import jermedit.gobjekte.Relationship;
import jermedit.gobjekte.Generalization;
import jermedit.gobjekte.Association;
import jermedit.gobjekte.ObjectifiedAssociation;
import jermedit.gobjekte.Entity;
import jermedit.gobjekte.SystemType;
import jermedit.gobjekte.PolygonObject;
import java.sql.*;

/**
 * Problems:
 * 1. First try to move a docked arrow dont refresh untill you move the Object it is attached to.
 * 
 * @author Jordan
 */
public class GuiJPanel extends JPanel implements MouseListener, MouseMotionListener {
   // Dimention area:
   private Dimension area;
   private final int D = 50;
   // Maus abfang Koordinaten:
   private int deltaX, deltaY;  // deltaX, deltaY definiert wo genau in der Objekt wir geklickt haben
   private int pos,posGer, posEp;
   private double anfeckX,anfeckY;             // der Index von der Objekt das angeklikt war
   private static String klasse;
   private boolean move,ziehen;        // wirt Jetzt gerade ein Objekt bewegt
   private Point neuPoint;      // nur in eine Methode benutzt also muss nicht hier definiert sein
   // Collections mit unseren Objekten:
   // Collection für Zeichenobjekte, Test: Wir benutzen diese Dimond Indicator das die neuen Syntax von Java leichter macht
   LinkedList<PolygonObject> listOfZeichenobjekte = new LinkedList<PolygonObject>();
   // Collection für Geraden, Test: versuchen wir der Oberklasse List zu benutzen :) und mit new LinkedList<Gerade>();
   LinkedList<LineObject> listOfGeraden = new LinkedList<LineObject>(); // Fehler:  Wieso sind das Instanzen von Gobjekt ??? und nicth von LineObject
   // Objekt zum Speichern
   Serializable saveList[] = new Serializable[2];
   private MouseState mouseState = MouseState.SELECTOR;
   private MouseState lineType;
   private boolean addingline = false;
   private Point newLineVonPoint;
   private Point newLineNachPoint;
 
   private int epNumber;
   private boolean epMove = false;
   
   private int epZoNumber;
//   private boolean epZoMove = false;
   private Point oldGeradePoint;
   private int Hand, Maus,Maus1,Mauspos;  // What is Hand used for?? 
   private int zoIDcounter = 0;
   
   private JPopupMenu popup; //Popmenue
   public static GuiJPanel window; // That's new, used for Printing the Project
   
   public GuiJPanel(){//constructor
     area = new Dimension(400,300);
     this.setPreferredSize( area);
     this.setBackground(new Color(255,255,255));
     window = this;
     addMouseMotionListener(this);
     addMouseListener(this);
     //Test Popup
        popup = new JPopupMenu();
        ActionListener menuListener = new ActionListener() {
        public void actionPerformed(ActionEvent event) {
//SOP            System.out.println("Popup menu item ["+ event.getActionCommand() + "] was pressed.");
            if(event.getActionCommand().equals("Umbenennen")){
                for (LineObject ger : listOfGeraden){
                        
                    if(ger.isSelected()==true){
                        if(ger instanceof Relationship)rename(ger,1);
                    break;
                    }
                }
                for (PolygonObject zo : listOfZeichenobjekte){
                    if(zo.isSelected()==true){
                        zo.umbenennen();
                        repaint();
                        break;
                    }
                }
             
            }
            if(event.getActionCommand().equals("Drucken")){
                new PrinterDriver(window);
             
            }
            if(event.getActionCommand().equals("Speichern")){
              dbSave();  
                 
        }
                  
            if(event.getActionCommand().equals("Löschen")){
                    deleteSelected();
            }
//+++++++++++++++++++++++++++++ TEST            
//            if(event.getActionCommand().equals("Add Point")){
//                for (LineObject ger : listOfGeraden){
//                    if(ger.isSelected()==true){
//                        ger.addEditPoint();
//                    break;
//                    }
//                }
//            }
//+++++++++++++++++++++++++++++ TEST              
        }
    };
// Mause Menu Items:        
        JMenuItem item;
        popup.add(item = new JMenuItem("Speichern"));
        item.addActionListener(menuListener);
        popup.add(item = new JMenuItem("Drucken"));
        item.addActionListener(menuListener);
        popup.add(item = new JMenuItem("Umbenennen"));
        item.addActionListener(menuListener);
        popup.add(item = new JMenuItem("Löschen"));
        item.addActionListener(menuListener);
// Test   +++++++++++++++++++++++++++++++++++++++++++++++++     
//        popup.add(item = new JMenuItem("Add Point"));
//        item.addActionListener(menuListener);
// Test    +++++++++++++++++++++++++++++++++++++++++++++++++         
        addMouseListener(new MousePopupListener());
//    Testende Popup
     
     
   }//end constructor
   
   @Override
   public void paintComponent(Graphics g){
     super.paintComponent(g); // Ohne das war unseren Scroll nicht so "SUPER" :)
     //Downcast the Graphics object to a Graphics2D object
     Graphics2D g2 = (Graphics2D)g;
    // Zeichnen von allen Objekte in listOfZeichenobjekte - Alle Zeichenobjekte
     for (PolygonObject ger : listOfZeichenobjekte){
         ger.draw(g2);
     }
     // Zeichnen von allen Objekte in listOfGeraden - Alle Geraden
     for (LineObject ger : listOfGeraden){
         ger.draw(g2);
         }
   }//end overridden paint()
      
     public void getGerade(LineObject a,Point b,String c){ 
        a.setSelected(false);
        repaint();
        //eigentliche Überprüfung 2 Pixel diff. zum klick um die Relationship
        int i = (int) Line2D.ptLineDist(a.getVonX(),a.getVonY(),a.getNachX(),a.getNachY(), b.x, b.y);
        if (i<2){
            System.out.println("Liegt nah genung: "+i);
            a.setSelected(true);
            repaint();
            // falls es sich um Relationship handelt kann sie neu bechriftet werden
            if ("Linie".equals(c)){
                System.out.println("passt");
                int alt = 1;
                rename(a,alt);
            }
        }else {
            System.out.println("zuweit weg: "+i);
        }
    }  

    public void rename(LineObject a,int b ){
        String  RName="";
        //Für Combobox vorbelegung
        String Relation =((Relationship)a).getRelation();
        //Verhältnisse die möglich sind
        JComboBox Rolle = new JComboBox(new String[]{"0:1", "1:1", "1:*","0:*"});
        Object[] message = {"Rolle wählen:", Rolle, "Name eingeben:"};

        // unterscheidung zwischen neuer Rolle oder bereits vorhandener Rolle
        switch (b){
            //Fall neue Relationship
            case 2:
                RName= (String)JOptionPane.showInputDialog(null, message, "Rolle und Verhältnis",JOptionPane.OK_CANCEL_OPTION);
                break;
            //Fall alte Relationship
            case 1:
                // vorbelengen der Combobox mit dem Verhältnis
                int sInt = 0;
                if(Relation.equals("0:1")){
                    sInt = 1;
                }else if(Relation.equals("1:1")){
                    sInt = 2;
                }else if(Relation.equals("1:*")){
                    sInt = 3;
                }else if(Relation.equals("0:*")){
                    sInt = 4;
                }
                
                switch (sInt){
                    case 1:
                        Rolle.setSelectedIndex(0);
                        break;
                    case 2:
                        Rolle.setSelectedIndex(1);
                        break;
                    case 3:
                        Rolle.setSelectedIndex(2);
                        break;
                    case 4:
                        Rolle.setSelectedIndex(3);
                        break;
                }
                RName= (String)JOptionPane.showInputDialog(null,message, "Rolle und Verhältnis",JOptionPane.OK_CANCEL_OPTION,null,null,((Relationship)a).getName());
                break;
        }              
        //Button Abbrechen abfangen
        if  (RName==(null)){
            JOptionPane.showMessageDialog(null,"Vorgang abgebrochen!");
                        }//abfangen falls kein Name eingegeben wird
                    else  if (RName.length()==0){
                            JOptionPane.showMessageDialog(null,"Keinen Wert eingegben!");    
                        }
                        else{
                            switch (b){
                            case 2:
                                if (a instanceof Relationship){
                                    ((Relationship)a).setName(RName);
                                    ((Relationship)a).setRelation((String)Rolle.getSelectedItem());
                                    listOfGeraden.add(((Relationship)a));
                                        }
// WTF Moment What is this Case for? b is suppose to be the Beggignign or end of the line? But nothing chages here except add or not add
                            case 1:
                                if (a instanceof Relationship){
                                    ((Relationship)a).setName(RName);
                                    ((Relationship)a).setRelation((String)Rolle.getSelectedItem());
                                    //((Relationship)a).rename(RName);
                                    //((Relationship)a).renameRel((String)Rolle.getSelectedItem());
                                    repaint();
                                        }
                                }
                        }
     }

     @Override
    public void mouseClicked(MouseEvent e) {
	if (SwingUtilities.isLeftMouseButton(e)){
            //Doppelklick für Rename
            int click=e.getClickCount();
            //Mouse Pos holen
            Point m = e.getPoint();
            //Rename
            if (click==2){
                for (LineObject ger : listOfGeraden){
                    //Überprüfen, ob der Klick auf einer Relationship,Generalization etc. ist.    
                    String name = ger.getClass().getSimpleName();
                    getGerade(ger,m,name);
                }
                for(PolygonObject zo : listOfZeichenobjekte){
                    if(zo.isInArea(e.getX(),e.getY() )){
                        String name="";

                        name = JOptionPane.showInputDialog(this,"Beschreibung eingeben: ");
                        if  (name==(null)){
                            JOptionPane.showMessageDialog(null,"Vorgang abgebrochen!");
                            }//abfangen falls kein Name eingegeben wird
                        else  
                        if (name.length()==0){
                            JOptionPane.showMessageDialog(null,"Keinen Wert eingegben!");   
                            }
                        else{
                        zo.umbenennen(name);
                        repaint();
                        }
                    }                
                }
            }
        }
        // wen wir neue objekte machen nemen wir die coordinaten von MouseEvent e
        if (SwingUtilities.isLeftMouseButton(e)){
            int deltalistOfGeraden = listOfGeraden.size();
            int deltalistOfZeichenobjekte = listOfZeichenobjekte.size();
            
            switch(mouseState){
                case SELECTOR: // funktioniert aber nur ven amn Klickt nicht wenn man zeht oder sonst mit der maus
                    // Selectieren von Objekt, deselektieren von anderen
                    boolean einGeradeSelectiert = false; // Helft uns zu wissen das ein LineObject ist Selectiert. Mehreren sollen nie selectiert sein. 
                    
                    if(!e.isControlDown())
                    {
                        this.deselectAll(); // if Ctrl not hold
                    }

                    for (LineObject ger : listOfGeraden){
                            if(ger.isInArea(e.getX(), e.getY())){
                                ger.setSelected(true);
                                einGeradeSelectiert = true;
                            }
                    }
                    
                    if(!einGeradeSelectiert){
                        for (PolygonObject ger : listOfZeichenobjekte){
                            if (ger.isInArea(e.getX(), e.getY())){
                                ger.setSelected(true);
                            }
                        }
                    }
                    
                    this.repaint();
                    break;
                case EUNMTYPE:
                    
                    listOfZeichenobjekte.add( new EnumType(e.getX(), e.getY(), zoIDcounter) );
                    if (!listOfZeichenobjekte.getLast().bUmbenennen()){
                        listOfZeichenobjekte.removeLast();
                    }
                    this.repaint();
                    this.zoIDcounter++;
                    break;
                case OBJECTTYPE:
                    listOfZeichenobjekte.add( new Entity(e.getX(), e.getY(), zoIDcounter) );
                    if (!listOfZeichenobjekte.getLast().bUmbenennen()){
                        listOfZeichenobjekte.removeLast();
                    }
                    this.repaint();
                    this.zoIDcounter++;
                    break;
                case ASSOSIATIONTYPE:
                    listOfZeichenobjekte.add( new Association(e.getX(), e.getY(), zoIDcounter) );
                    if (!listOfZeichenobjekte.getLast().bUmbenennen()){
                        listOfZeichenobjekte.removeLast();
                    }
                    this.repaint();
                    this.zoIDcounter++;
                    break;
                case OBJASSTYPE:
                    listOfZeichenobjekte.add( new ObjectifiedAssociation(e.getX(), e.getY(), zoIDcounter) );
                    if (!listOfZeichenobjekte.getLast().bUmbenennen()){
                        listOfZeichenobjekte.removeLast();
                    }
                    this.repaint();
                    this.zoIDcounter++;
                    break;
                case BASETYPE:
                    listOfZeichenobjekte.add( new BaseType(e.getX(), e.getY(), zoIDcounter) );
                    if (!listOfZeichenobjekte.getLast().bUmbenennen()){
                        listOfZeichenobjekte.removeLast();
                    }
                    this.repaint();
                    this.zoIDcounter++;
                    break;
                case SYSTEMTYPE:
                    listOfZeichenobjekte.add( new SystemType(e.getX(), e.getY(), zoIDcounter));
                    if (!listOfZeichenobjekte.getLast().bUmbenennen()){
                        listOfZeichenobjekte.removeLast();
                    }
                    this.repaint();
                    this.zoIDcounter++;
                    break;
                case XOR:
                    listOfZeichenobjekte.add( new DerivationNod(e.getX(), e.getY(), zoIDcounter) );
                    if (!listOfZeichenobjekte.getLast().bUmbenennen()){
                        listOfZeichenobjekte.removeLast();
                    }
                    this.repaint();
                    this.zoIDcounter++;
                    break;
                // LineObject Zeichnen ----------------------------------------------------------
                case ADDINGLINE:
                    int vonZOindex = -1, nachZOindex = -1;
                    boolean vonZO = false ,nachZO = false;
                    if (addingline == false){
                    // -- Fisrt stage, first point is there and first object
                        this.newLineVonPoint = new Point (e.getX(), e.getY());
                        
                        // add LineObject marker
                        
                        switch (lineType){
                            case ASSOTIATION:
                                    listOfGeraden.add(new Relationship(e.getX(), e.getY(),e.getX(), e.getY() )); 
//                                    int neu = 2;
//                                    rename(listOfGeraden.getLast(),neu);
                                    break;
                                case GENERALIZATION:
                                    listOfGeraden.add(new Generalization(e.getX(), e.getY(),e.getX(), e.getY() )); 
                                    break;
                                case REPRESENTEDBY:
                                    listOfGeraden.add( new RepresentedBy( e.getX(), e.getY(),e.getX(), e.getY() ));
                                    break;
                                default:
                                    System.err.println("Wir wollten Gerade zeichen, hatten keine Gerade in der Hand");
                                    break;
                        }
                        
                        this.addingline = true;
                    }else{ // Second satge of adding line
                        // remove LineObject marker
                        if(!listOfGeraden.isEmpty())listOfGeraden.remove(listOfGeraden.size()-1);
                        
                        this.newLineNachPoint = new Point (e.getX(), e.getY());
// ObjAssTyp hie logich eindocken auf der AssTyp berechnen wenn der ger ein ObjAssTyp ist                        
                        for (PolygonObject ger : listOfZeichenobjekte){
                                   if ( ger.isInArea( (int)this.newLineVonPoint.getX(),(int)this.newLineVonPoint.getY() ) ){
                                       vonZO = true;
//                                       vonZOindex = ger.getId();
                                       vonZOindex = listOfZeichenobjekte.indexOf(ger);
                                   }
                        }
                        
                        for (PolygonObject ger : listOfZeichenobjekte){
                            if ( ger.isInArea( (int)this.newLineNachPoint.getX(),(int)this.newLineNachPoint.getY() ) ){
                                nachZO = true;
//                                nachZOindex = ger.getId();
                                nachZOindex = listOfZeichenobjekte.indexOf(ger);
                            }
                        }
                        // Logik für Linien und Objekte
                        
                        // generieren von der richtigen punkte fuer Positionen des LineObject
                        if(vonZO && nachZO){ 
                            LineObject gerade;
                            int gx1 = -1,gy1 = -1, gx2 = -1,gy2 = -1; // wir nehmen an wir haben kein Negativen Koordinaten
//                          
                            int vonZOid = listOfZeichenobjekte.get(vonZOindex).getId();
                            int nachZOid = listOfZeichenobjekte.get(nachZOindex).getId();
                            int [] rec; 
//                            int vonZOindex = vonZOindex1, nachZOindex = nachZOindex1;
                            switch (lineType){
/* Cration von Geraden ************************************************************************************/
                                case ASSOTIATION:
                                    //gerade = new Relationship( listOfZeichenobjekte.get(vonZOindex).getX(),listOfZeichenobjekte.get(vonZOindex).getY(), listOfZeichenobjekte.get(nachZOindex).getX(),listOfZeichenobjekte.get(nachZOindex).getY() ); 
                                    if(!(((listOfZeichenobjekte.get(vonZOindex) instanceof Entity)&&(listOfZeichenobjekte.get(nachZOindex)instanceof Association)) ||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof Association)&&(listOfZeichenobjekte.get(nachZOindex)instanceof Entity))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof BaseType)&&(listOfZeichenobjekte.get(nachZOindex)instanceof Association)) ||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof Association)&&(listOfZeichenobjekte.get(nachZOindex)instanceof BaseType)) ||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof SystemType)&&(listOfZeichenobjekte.get(nachZOindex)instanceof Association)) ||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof Association)&&(listOfZeichenobjekte.get(nachZOindex)instanceof SystemType))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof EnumType)&&(listOfZeichenobjekte.get(nachZOindex)instanceof Association))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof Association)&&(listOfZeichenobjekte.get(nachZOindex)instanceof EnumType))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof ObjectifiedAssociation)&&(listOfZeichenobjekte.get(nachZOindex)instanceof Association))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof Association)&&(listOfZeichenobjekte.get(nachZOindex)instanceof ObjectifiedAssociation))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof ObjectifiedAssociation)&&(listOfZeichenobjekte.get(nachZOindex)instanceof Entity))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof Entity)&&(listOfZeichenobjekte.get(nachZOindex)instanceof ObjectifiedAssociation))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof ObjectifiedAssociation)&&(listOfZeichenobjekte.get(nachZOindex)instanceof BaseType))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof BaseType)&&(listOfZeichenobjekte.get(nachZOindex)instanceof ObjectifiedAssociation))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof ObjectifiedAssociation)&&(listOfZeichenobjekte.get(nachZOindex)instanceof SystemType))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof ObjectifiedAssociation)&&(listOfZeichenobjekte.get(nachZOindex)instanceof EnumType))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof EnumType)&&(listOfZeichenobjekte.get(nachZOindex)instanceof ObjectifiedAssociation))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof SystemType)&&(listOfZeichenobjekte.get(nachZOindex)instanceof ObjectifiedAssociation)))){
                                        
                                        System.out.println("err Asso");
                                    }
                                    else{
                                    gerade = new Relationship(gx1,gy1,gx2,gy2 ); 
                                    gerade.setVonZOindex(vonZOid);
                                    gerade.setNachZOindex(nachZOid);
                                    rec = recalcGeradePositions(gerade);
                                    gerade.setPointx(1, rec[0], rec[1]); 
                                    gerade.setPointx(2, rec[2], rec[3]);
                                    //listOfGeraden.add(gerade);
                                    int neu = 2;
                                    rename(gerade,neu);     // Adiert die Relationship
                                    }
                                    break;
                                case GENERALIZATION:
                                    if( !(( listOfZeichenobjekte.get(vonZOindex) instanceof Entity  ) && (listOfZeichenobjekte.get(nachZOindex) instanceof Entity )||
                                            ((listOfZeichenobjekte.get(vonZOindex)instanceof DerivationNod)&&(listOfZeichenobjekte.get(nachZOindex)instanceof Entity))||
                                            ((listOfZeichenobjekte.get(vonZOindex) instanceof Entity)&&(listOfZeichenobjekte.get(nachZOindex)instanceof DerivationNod)))){
                                        System.out.println("Genrel err");
                                    }else{
                                        System.out.println("Passt aber err");
                                        gerade = new Generalization(gx1,gy1,gx2,gy2 ); 
                                        gerade.setVonZOindex(vonZOid);
                                        gerade.setNachZOindex(nachZOid);
                                        rec = recalcGeradePositions(gerade);
                                        gerade.setPointx(1, rec[0], rec[1]); 
                                        gerade.setPointx(2, rec[2], rec[3]);
                                        listOfGeraden.add(gerade);
                                    }
                                    break;
                                case REPRESENTEDBY:
                                if(!((listOfZeichenobjekte.get(vonZOindex) instanceof BaseType) && (listOfZeichenobjekte.get(nachZOindex)instanceof Entity) ||
                                         (listOfZeichenobjekte.get(vonZOindex) instanceof SystemType) && (listOfZeichenobjekte.get(nachZOindex)instanceof Entity) )  ){
                                        System.out.println("err");
                                    }
                                    else{
                                    gerade = new RepresentedBy( gx1,gy1,gx2,gy2 );
                                    gerade.setVonZOindex(vonZOid);
                                    gerade.setNachZOindex(nachZOid);
                                    rec = recalcGeradePositions(gerade);
                                    gerade.setPointx(1, rec[0], rec[1]); 
                                    gerade.setPointx(2, rec[2], rec[3]);
                                    listOfGeraden.add(gerade);
                                    }
                                    break;
                                default:
                                    System.err.println("Wir wollten Gerade zeichen, hatten keine Gerade in der Hand");
                                    break;
                            }
                        }
                        mouseState = MouseState.SELECTOR;
                        this.addingline = false;
//                        System.out.println("repaint");
                        repaint();
                    }

                    break;
                default:
                    System.err.println("Ein Maus braucht immer ein Pass!");
                    break; 
            }// End of Switch
            // Nach der Objekt kreation, soll der Maus ein normalen Zeiger sein. Aber vorsicht mit der linien die brauchen zweiten durchgang
            if(mouseState != MouseState.ADDINGLINE){
                mouseState = MouseState.SELECTOR;
            } 
            
            if(deltalistOfGeraden != listOfGeraden.size()){
                if(!e.isControlDown())
                    {
                        this.deselectAll(); // if Ctrl not hold
                    }
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!                
                if(!listOfGeraden.isEmpty())listOfGeraden.getLast().setSelected(true);
            }
            if(deltalistOfZeichenobjekte != listOfZeichenobjekte.size()){
                if(!e.isControlDown())
                    {
                        this.deselectAll(); // if Ctrl not hold
                    }
                listOfZeichenobjekte.getLast().setSelected(true);
            }
        }
    }
    
    @Override
    public void mousePressed(MouseEvent e) {
/* WTF This makes Problem 1 appear.
        if (SwingUtilities.isLeftMouseButton(e)){
            for (PolygonObject ger : listOfZeichenobjekte){
                String Objekt= ger.getClass().getSimpleName();
                
                if (Objekt.equals("Systemtyp")||Objekt.equals("Enumtyp")||Objekt.equals("Basistyp")||Objekt.equals("Rechteck")||Objekt.equals("RauteRechteck")){
                    if (e.getX()> ger.linkerObenEckpunkt().getX()-3 && e.getX()< ger.linkerObenEckpunkt().getX()+3 && e.getY()>ger.linkerObenEckpunkt().getY()-3&& e.getY()<ger.linkerObenEckpunkt().getY()+3){
                        ziehen = true;
                        Hand=1;
                        anfeckX = ger.linkerObenEckpunkt().getX();
                        anfeckY = ger.linkerObenEckpunkt().getY();
                        Mauspos=1;                                     
                    } 
                    if(e.getX()> ger.rechterObenEckpunkt().getX()-3 && e.getX()< ger.rechterObenEckpunkt().getX()+3 && e.getY()>ger.rechterObenEckpunkt().getY()-3&& e.getY()<ger.rechterObenEckpunkt().getY()+3 ){
                        ziehen = true;
                        Hand=1;
                        anfeckX = ger.rechterObenEckpunkt().getX();
                        anfeckY = ger.rechterObenEckpunkt().getY();
                        Mauspos=2;                        
                    }
                    if(e.getX()> ger.linkerUntenEckpunkt().getX()-3 && e.getX()< ger.linkerUntenEckpunkt().getX()+3 && e.getY()>ger.linkerUntenEckpunkt().getY()-3&& e.getY()<ger.linkerUntenEckpunkt().getY()+3 ){
                        ziehen = true;
                        Hand=1;
                        anfeckX = ger.linkerUntenEckpunkt().getX();
                        anfeckY = ger.linkerUntenEckpunkt().getY();
                        Mauspos=3;                       
                    }
                    if(e.getX()> ger.rechterUntenEckpunkt().getX()-3 && e.getX()< ger.rechterUntenEckpunkt().getX()+3 && e.getY()>ger.rechterUntenEckpunkt().getY()-3&& e.getY()<ger.rechterUntenEckpunkt().getY()+3) {
                        ziehen = true;
                        Hand=1;
                        anfeckX = ger.rechterUntenEckpunkt().getX();
                        anfeckY = ger.rechterUntenEckpunkt().getY();
                        Mauspos=4;                        
                    }
                }
                else 
                        
                    if(e.getX()> ger.mitteLinks().getX()-3 && e.getX()< ger.mitteLinks().getX()+3 && e.getY()>ger.mitteLinks().getY()-3&& e.getY()<ger.mitteLinks().getY()+3 ){
                        
                        ziehen = true;
                        Hand=1;
                        anfeckX = ger.mitteLinks().getX();
                        anfeckY = ger.mitteLinks().getY();
                        Mauspos=5;
                                                
                    }
                    if(e.getX()> ger.mitteRechts().getX()-3 && e.getX()< ger.mitteRechts().getX()+3 && e.getY()>ger.mitteRechts().getY()-3&& e.getY()<ger.mitteRechts().getY()+3 ){
                        ziehen = true;
                        Hand=1;
                        anfeckX = ger.mitteRechts().getX();
                        anfeckY = ger.mitteRechts().getY();
                        Mauspos=6;
                        
                    }

                    if(e.getX()> ger.mitteOben().getX()-3 && e.getX()< ger.mitteOben().getX()+3 && e.getY()>ger.mitteOben().getY()-3&& e.getY()<ger.mitteOben().getY()+3 ){
                        ziehen = true;
                        Hand=1;
                        anfeckX = ger.mitteOben().getX();
                        anfeckY = ger.mitteOben().getY();
                        Mauspos=7;                         
                    }
                    if(e.getX()> ger.mitteUnten().getX()-3 && e.getX()< ger.mitteUnten().getX()+3 && e.getY()>ger.mitteUnten().getY()-3&& e.getY()<ger.mitteUnten().getY()+3 ){
                        ziehen = true;
                        Hand=1;
                        anfeckX = ger.mitteUnten().getX();
                        anfeckY = ger.mitteUnten().getY();
                        Mauspos=8;
                    }
                
                }
            }
*/
        if (SwingUtilities.isLeftMouseButton(e)){
            // mark the EditPoint of LineObject, watch the upper for it still works
            for (LineObject ger : listOfGeraden){
                if (ger.isSelected()){
                    if(ger.getVonEP().contains(e.getX(),e.getY())){
                        oldGeradePoint = new Point(ger.getVonX(), ger.getVonY());
                        posGer = listOfGeraden.indexOf(ger);
                        epNumber = 1;
                        epMove = true;
                        return;
                    }
                    if(ger.getNachEP().contains(e.getX(),e.getY())){
                        oldGeradePoint = new Point(ger.getNachX(), ger.getNachY());
                        posGer = listOfGeraden.indexOf(ger);
                        epNumber = 2;
                        epMove = true;
                        return;
                    }
                }
            }
            
            for (PolygonObject ger : listOfZeichenobjekte){
                if (ger.isInArea(e.getX(),e.getY())){
                    if(!e.isControlDown())
                    {
                        this.deselectAll(); // if Ctrl not hold
                    }
                    ger.setSelected(true);
                    deltaX = ger.getX()-e.getX(); deltaY = ger.getY()-e.getY();
                    pos = listOfZeichenobjekte.indexOf(ger);
                    move = true;
                }
            }
        }
    }
    
    @Override
    public void mouseReleased(MouseEvent e) {
        // move of LineObject Points
        if(epMove){
            boolean foundZO = false;
            for (PolygonObject ger : listOfZeichenobjekte){
                        if(ger.isInArea(e.getX(), e.getY())){
//                            listOfGeraden.get(posGer).setPointx(epNumber, e.getX(),e.getY());
                            listOfGeraden.get(posGer).setZOindexX(epNumber,ger.getId()); // sets the new ZO of the LineObject .old: istOfZeichenobjekte.indexOf(ger)
                            // Set the Line at the Generated Positions for the new Object
// Problem 1 solved:                            
//                            int indexZoID = ger.getId();
                            
                            if(listOfGeraden.get(posGer).getVonZOindex() != -1 || listOfGeraden.get(posGer).getNachZOindex() != -1 ){
                                int [] rec =  recalcGeradePositions(listOfGeraden.get(posGer));
                                listOfGeraden.get(posGer).setPointx(1, rec[0], rec[1]); 
                                listOfGeraden.get(posGer).setPointx(2, rec[2], rec[3]); 
                            }
                            foundZO = true;
                            repaint();
                            break;
                        }
            }
            if (!foundZO){
                // resets the old location
                listOfGeraden.get(posGer).setPointx(epNumber, oldGeradePoint.x,oldGeradePoint.y);
                repaint();
            }
            
        }
        ziehen = false;
        move = false;
        epMove = false;
//        epZoMove = false;
        setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        Hand=0;
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        
    }

    @Override
    public void mouseExited(MouseEvent e) {
        
    }

    /*
     * Too Big! WTF
     */
    @Override
    public void mouseDragged(MouseEvent e) {
        
        switch(Hand) {
            case 1:           
                if (SwingUtilities.isLeftMouseButton(e)){
                    for (PolygonObject ger : listOfZeichenobjekte){
                        if (ger.isSelected()){
                            if(ziehen){
                            //Brechnung der Veränderung der Breite(absolut)
                            int verX = (int)anfeckX-e.getX();  
                            int verY = (int)anfeckY-e.getY();


                                    //Maus bewegt sich nach links
                                    if (Maus>e.getX()&Maus1==e.getY()){                                    
                                        switch(Mauspos){
                                            //Maus befindet sich links oben am Eck
                                            case 1:

                                                //Berechnung der neuen Breite = alte Breite + (X-Coord von Eckpunkt)-Mauspostion
                                                int br1=ger.getBreite()+ger.linkerObenEckpunkt().x-e.getX();

                                                if ( br1>=100&ger.getClass().getSimpleName().equals("RauteRechteck")){

                                                    ger.setBreite(br1);
                                                    //Überprüfen ob ObjectifiedAssociation, falls ja Association mitvergrößern
                                                    if(ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                        int be = ((ObjectifiedAssociation)ger).getRauteBreite()+ger.linkerObenEckpunkt().x-e.getX();
                                                        ((ObjectifiedAssociation)ger).setRauteBreite(be);                                                    
                                                    }

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()-1, ger.getY());
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX()-1,ger.getY());
                                                        repaint();
                                                    }                                               
                                                }
                                                if(br1>=60&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setBreite(br1);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()-1, ger.getY());
                                                        repaint();
                                                    }
                                                }
                                            //Maus befindet sich rechts Oben am Eck
                                            case 2:

                                                int br2=ger.getBreite()-(ger.rechterObenEckpunkt().x-e.getX());

                                                //Überprüfen ob ObjectifiedAssociation, falls ja Association mitvergrößern
                                                if ( br2>=100&ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setBreite(br2);
                                                    if(ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                        int be = ((ObjectifiedAssociation)ger).getRauteBreite()-(ger.rechterObenEckpunkt().x-e.getX());

                                                        ((ObjectifiedAssociation)ger).setRauteBreite(be);
                                                    }
                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()-1, ger.getY());
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX()-1,ger.getY());

                                                        repaint();
                                                    }
                                                }
                                                if(br2>=60&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setBreite(br2);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()-1, ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                break;
                                            //Maus befindet sich links unten am Eck                                       
                                            case 3:

                                                int br3=ger.getBreite()+ger.linkerUntenEckpunkt().x-e.getX();
    //                                            System.out.println("links unten und nach links verschieben");
                                                //Überprüfen ob ObjectifiedAssociation, falls ja Association mitvergrößern
                                                if ( br3>=100&ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setBreite(br3);
                                                    int be = ((ObjectifiedAssociation)ger).getRauteBreite()+ger.linkerUntenEckpunkt().x-e.getX();
                                                    ((ObjectifiedAssociation)ger).setRauteBreite(be);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()-1, ger.getY());
    //                                                    ((ObjectifiedAssociation)ger).getRaute().setX(ger.getX()-1);
    //                                                    ((ObjectifiedAssociation)ger).getRaute().setY(ger.getY());
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX()-1,ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                if(br3>=60&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setBreite(br3);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()-1, ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                break;
                                            //Maus befindet sich rechts unten am Eck
                                            case 4:

                                                int br4=ger.getBreite()-(ger.rechterUntenEckpunkt().x-e.getX());
    //                                            System.out.println("rechts unten und nach links verschieben");
                                                //Überprüfen ob ObjectifiedAssociation, falls ja Association mitvergrößern
                                                if (br4>=100&ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setBreite(br4);
                                                    int be = ((ObjectifiedAssociation)ger).getRauteBreite()-(ger.rechterUntenEckpunkt().x-e.getX());
                                                    ((ObjectifiedAssociation)ger).setRauteBreite(be);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()-1, ger.getY());
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX()-1,ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                if(br4>=60&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setBreite(br4);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()-1, ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                break;
                                            //Maus befindet sich mitte links bei Association, DerivationNod und NamenskonventionDel 
                                            case 5:
                                                //Fallunterscheidung Association/Kreis/Namenskonvention 

                                                int iSwitch = 0;
                                                if (ger.getClass().getSimpleName().equals("Raute")){
                                                    iSwitch = 1;
                                                }else if (ger.getClass().getSimpleName().equals("Kreis")){
                                                    iSwitch = 2;
                                                }else if (ger.getClass().getSimpleName().equals("Namenskonvention")){
                                                    iSwitch = 3;
                                                }

                                                switch (iSwitch) {
                                                    case 1:{
                                                        int br5=ger.getBreite()+(ger.mitteLinks().x-e.getX());
                                                        if ( br5>=30){
                                                            ger.setBreite(br5);

                                                            if(verX % 2== 0){
                                                                ger.setPos(ger.getX()-1, ger.getY());
                                                                repaint();
                                                            }
                                                        }
                                                    break;
                                                    }
                                                    case 2:{
                                                        int br5=ger.getBreite()+(ger.mitteLinks().x-e.getX());
                                                        if ( br5>=20){
                                                            ger.setBreite(br5);

                                                            if(verX % 2== 0){
                                                                ger.setPos(ger.getX()-1, ger.getY());
                                                                repaint();
                                                            }
                                                         }
                                                    break;
                                                    }
                                                    case 3:{
                                                        int br5=ger.getBreite()+(ger.mitteLinks().x-e.getX());
                                                        if ( br5>=15){
                                                            ger.setBreite(br5);

                                                            if(verX % 2== 0){
                                                                ger.setPos(ger.getX()-1, ger.getY());
                                                                repaint();
                                                            }
                                                         }
                                                    break;                                                    
                                                    }
                                                }

                                                break;
                                            //Maus befindet sich mitte/rechts bei DerivationNod/Raute/Namenskonvention 
                                            case 6:
                                                //Fallunterscheidung DerivationNod/Raute/Namenskonvention 
                                                int iSwitch6 = 0;
                                                if (ger.getClass().getSimpleName().equals("Raute")){
                                                    iSwitch6 = 1;
                                                }else if (ger.getClass().getSimpleName().equals("Kreis")){
                                                    iSwitch6 = 2;
                                                }else if (ger.getClass().getSimpleName().equals("Namenskonvention")){
                                                    iSwitch6 = 3;
                                                }
                                                switch (iSwitch6) {
                                                    case 1:{
                                                        int br6=ger.getBreite()-(ger.mitteRechts().x-e.getX());

                                                        if ( br6>=30){
                                                            ger.setBreite(br6);

                                                            if(verX % 2== 0){
                                                                ger.setPos(ger.getX()-1, ger.getY());
                                                                repaint();
                                                            }
                                                        }
                                                    break;
                                                    }
                                                    case 2:{
                                                        int br6=ger.getBreite()-(ger.mitteRechts().x-e.getX());

                                                        if ( br6>=20){
                                                           ger.setBreite(br6);

                                                           if(verX % 2== 0){
                                                               ger.setPos(ger.getX()-1, ger.getY());
                                                               repaint();
                                                           }
                                                       }
                                                    break; 
                                                    }
                                                    case 3:{
                                                        int br6=ger.getBreite()-(ger.mitteRechts().x-e.getX());

                                                        if ( br6>=15){
                                                           ger.setBreite(br6);

                                                           if(verX % 2== 0){
                                                               ger.setPos(ger.getX()-1, ger.getY());
                                                               repaint();
                                                           }
                                                       }
                                                    break;                                                    
                                                    }
                                                }
                                                break;
                                        }                                
                                    }
                                    //Maus bewegt sich nach rechts
                                    else if(Maus<e.getX()&Maus1==e.getY()){

                                        switch(Mauspos){
                                            //Maus befindet sich links oben am Eck
                                            case 1:

                                                int br1=ger.getBreite()+ger.linkerObenEckpunkt().x-e.getX();
                                                if ( br1>=100&ger.getClass().getSimpleName().equals("RauteRechteck")){

                                                    ger.setBreite(br1);
                                                    int be = ((ObjectifiedAssociation)ger).getRauteBreite()+ger.linkerObenEckpunkt().x-e.getX();
                                                    ((ObjectifiedAssociation)ger).setRauteBreite(be);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()+1, ger.getY());
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX()+1,ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                if(br1>=60&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setBreite(br1);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()+1, ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                break;
                                            //Maus befindet sich rechts oben am Eck    
                                            case 2:

                                                int br2=ger.getBreite()-(ger.rechterObenEckpunkt().x-e.getX());                                           
                                                if ( br2>=100&ger.getClass().getSimpleName().equals("RauteRechteck")){

                                                    ger.setBreite(br2);
                                                    int be = ((ObjectifiedAssociation)ger).getRauteBreite()-(ger.rechterObenEckpunkt().x-e.getX());
                                                    ((ObjectifiedAssociation)ger).setRauteBreite(be);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()+1, ger.getY());
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX()+1,ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                if(br2>=60&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setBreite(br2);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()+1, ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                break;
                                            //Maus befindet sich links unten am Eck
                                            case 3:
                                                int br3=ger.getBreite()+ger.linkerUntenEckpunkt().x-e.getX();
                                                if ( br3>=100&ger.getClass().getSimpleName().equals("RauteRechteck")){

                                                    ger.setBreite(br3);
                                                    int be = ((ObjectifiedAssociation)ger).getRauteBreite()+ger.linkerUntenEckpunkt().x-e.getX();
                                                    ((ObjectifiedAssociation)ger).setRauteBreite(be);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()+1, ger.getY());
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX()+1, ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                if(br3>=60&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setBreite(br3);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()+1, ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                break;
                                            ////Maus befindet sich rechts unten am Eck
                                            case 4:
                                                int br4=ger.getBreite()-(ger.rechterUntenEckpunkt().x-e.getX());
                                                if ( br4>=100&ger.getClass().getSimpleName().equals("RauteRechteck")){

                                                    ger.setBreite(br4);
                                                    int be = ((ObjectifiedAssociation)ger).getRauteBreite()-(ger.rechterUntenEckpunkt().x-e.getX());
                                                    ((ObjectifiedAssociation)ger).setRauteBreite(be);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()+1, ger.getY());
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX()+1,ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                if(br4>=60&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setBreite(br4);

                                                    if(verX % 2== 0){
                                                        ger.setPos(ger.getX()+1, ger.getY());
                                                        repaint();
                                                    }
                                                }
                                                break;
                                           //Maus mitte/links bei Association/Kreis/Namenskonvention
                                             case 5:
                                                 //Fallunterscheidung Association/Kreis/Namenskonvention
                                                int iSwitch5 = 0;
                                                if (ger.getClass().getSimpleName().equals("Raute")){
                                                    iSwitch5 = 1;
                                                }else if (ger.getClass().getSimpleName().equals("Kreis")){
                                                    iSwitch5 = 2;
                                                }else if (ger.getClass().getSimpleName().equals("Namenskonvention")){
                                                    iSwitch5 = 3;
                                                }
                                                switch (iSwitch5) {
                                                    case 1:{
                                                        int br5=ger.getBreite()+(ger.mitteLinks().x-e.getX());

                                                        if ( br5>=30){
                                                           ger.setBreite(br5);

                                                           if(verX % 2== 0){
                                                               ger.setPos(ger.getX()+1, ger.getY());
                                                               repaint();
                                                           }
                                                       }
                                                    break;
                                                    }
                                                    case 2:{
                                                        int br5=ger.getBreite()+(ger.mitteLinks().x-e.getX());
                                                        if ( br5>=20){
                                                            ger.setBreite(br5);

                                                            if(verX % 2== 0){
                                                                ger.setPos(ger.getX()+1, ger.getY());
                                                                repaint();
                                                            }
                                                         }
                                                    break;
                                                    }
                                                    case 3:{
                                                        int br5=ger.getBreite()+(ger.mitteLinks().x-e.getX());
                                                        if ( br5>=15){
                                                            ger.setBreite(br5);

                                                            if(verX % 2== 0){
                                                                ger.setPos(ger.getX()+1, ger.getY());
                                                                repaint();
                                                            }
                                                         }
                                                    break;                                                    
                                                    }
                                                }

                                                break;
                                             //Maus befindet sich bei mitte/rechts bei Association/Kreis/Namenskonvention
                                             case 6:
                                                //Fallunterscheidung Association/Kreis/Namenskonvention
                                                int iSwitch6 = 0;
                                                if (ger.getClass().getSimpleName().equals("Raute")){
                                                    iSwitch6 = 1;
                                                }else if (ger.getClass().getSimpleName().equals("Kreis")){
                                                    iSwitch6 = 2;
                                                }else if (ger.getClass().getSimpleName().equals("Namenskonvention")){
                                                    iSwitch6 = 3;
                                                }
                                                switch (iSwitch6) {
                                                    case 1:{
                                                        int br6=ger.getBreite()-(ger.mitteRechts().x-e.getX());

                                                        if ( br6>=30){
                                                           ger.setBreite(br6);

                                                           if(verX % 2== 0){
                                                               ger.setPos(ger.getX()+1, ger.getY());
                                                               repaint();
                                                           }
                                                       }
                                                    break;
                                                    }
                                                    case 2:{
                                                        int br6=ger.getBreite()-(ger.mitteRechts().x-e.getX());

                                                        if ( br6>=20){
                                                           ger.setBreite(br6);

                                                           if(verX % 2== 0){
                                                               ger.setPos(ger.getX()+1, ger.getY());
                                                               repaint();
                                                           }
                                                       }
                                                    break; 
                                                    }
                                                    case 3:{
                                                        int br6=ger.getBreite()-(ger.mitteRechts().x-e.getX());

                                                        if ( br6>=15){
                                                           ger.setBreite(br6);

                                                           if(verX % 2== 0){
                                                               ger.setPos(ger.getX()+1, ger.getY());
                                                               repaint();
                                                           }
                                                       }
                                                    break;                                                    
                                                    }
                                                }

                                        }
                                    }

                                    if(Maus==e.getX()&Maus1<e.getY()){

                                        //Maus bewegt sich nach unten
                                        switch(Mauspos){
                                            //links oben
                                            case 1:
                                                int la=ger.getLaenge()+ger.linkerObenEckpunkt().y-e.getY();

                                                if ( la>=50&ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                ger.setLaenge(la);
                                                    if(ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                        int be = ((ObjectifiedAssociation)ger).getRauteLaenge()+ger.linkerObenEckpunkt().y-e.getY();

                                                        ((ObjectifiedAssociation)ger).setRauteLaenge(be);
                                                    }
                                                    if( verY % 2 ==0){

                                                        ger.setPos(ger.getX(), ger.getY()+1);
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX(),ger.getY()+1);
                                                        repaint();
                                                    }
                                                }
                                                if(la>=30&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la);
                                                    if( verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()+1);
                                                        repaint();
                                                    }
                                                }
                                                break;

                                            //rechts oben
                                            case 2:
                                                int la2=ger.getLaenge()+ger.rechterObenEckpunkt().y-e.getY();                                           
                                                if ( la2>=50&ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la2);
                                                    if(ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                        int be = ((ObjectifiedAssociation)ger).getRauteLaenge()+ger.rechterObenEckpunkt().y-e.getY();

                                                        ((ObjectifiedAssociation)ger).setRauteLaenge(be);
                                                    }
                                                    if( verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()+1);
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX(),ger.getY()+1);
                                                    repaint();
                                                    }
                                                }
                                                if(la2>=30&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la2);
                                                    if( verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()+1);

                                                    repaint();
                                                    }
                                                }
                                                break;
                                            //links unten
                                            case 3:

                                                int la3=ger.getLaenge()-(ger.linkerUntenEckpunkt().y-e.getY());                                          
                                                if ( la3>=50&ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la3);
                                                    if(ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                        int be = ((ObjectifiedAssociation)ger).getRauteLaenge()-(ger.linkerUntenEckpunkt().y-e.getY());

                                                        ((ObjectifiedAssociation)ger).setRauteLaenge(be);                                 
                                                    }
                                                    if( verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()+1);
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX(),ger.getY()+1);
                                                        repaint();
                                                    }
                                                }
                                                if(la3>=30&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la3);
                                                    if( verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()+1);
                                                    repaint();
                                                    }
                                                }
                                                break;  
                                            //rechts unten 
                                            case 4:

                                                int la4=ger.getLaenge()-(ger.rechterUntenEckpunkt().y-e.getY());                                          
                                                if ( la4>=50&ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                ger.setLaenge(la4);
                                                    if(ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                        int be = ((ObjectifiedAssociation)ger).getRauteLaenge()-(ger.rechterUntenEckpunkt().y-e.getY());

                                                        ((ObjectifiedAssociation)ger).setRauteLaenge(be);
                                                    }
                                                    if( verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()+1);
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX(),ger.getY()+1);
                                                    repaint();
                                                    }
                                                }
                                                if(la4>=30&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la4);
                                                    if( verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()+1);
                                                    repaint();
                                                    }
                                                }
                                                break;
                                            case 7:
                                                int iSwitch7 = 0;
                                                if (ger.getClass().getSimpleName().equals("Raute")){
                                                    iSwitch7 = 1;
                                                }else if (ger.getClass().getSimpleName().equals("Kreis")){
                                                    iSwitch7 = 2;
                                                }else if (ger.getClass().getSimpleName().equals("Namenskonvention")){
                                                    iSwitch7 = 3;
                                                }
                                                switch(iSwitch7){
                                                    case 1:{

                                                        int la7=ger.getLaenge()+(ger.mitteOben().y-e.getY());

                                                        if (la7>=15){
                                                            ger.setLaenge(la7);

                                                            if( verY % 2 ==0){
                                                            ger.setPos(ger.getX(), ger.getY()+1);
                                                            repaint();
                                                            }
                                                        }
                                                    break;
                                                    }
                                                    case 2:{
                                                        int la7=ger.getLaenge()+(ger.mitteOben().y-e.getY());

                                                        if (la7>=20){
                                                            ger.setLaenge(la7);

                                                            if( verY % 2 ==0){
                                                            ger.setPos(ger.getX(), ger.getY()+1);
                                                            repaint();
                                                            }
                                                        }
                                                    break;
                                                    }
                                                    case 3:{
                                                        int la7=ger.getLaenge()+(ger.mitteOben().y-e.getY());

                                                        if (la7>=15){
                                                            ger.setLaenge(la7);

                                                            if( verY % 2 ==0){
                                                            ger.setPos(ger.getX(), ger.getY()+1);
            //                                    System.out.println("neuer Mittelpunkt X: "+ger.getX()+ " Mittelpunkt Y:: "+ ger.getY());
                                                            repaint();
                                                            }
                                                        }
                                                    break;                                                    
                                                    }
                                                    }
                                            case 8:
                                                int iSwitch8 = 0;
                                                if (ger.getClass().getSimpleName().equals("Raute")){
                                                    iSwitch8 = 1;
                                                }else if (ger.getClass().getSimpleName().equals("Kreis")){
                                                    iSwitch8 = 2;
                                                }else if (ger.getClass().getSimpleName().equals("Namenskonvention")){
                                                    iSwitch8 = 3;
                                                }
                                                switch(iSwitch8){
                                                    case 1:{
                                                        int la8=ger.getLaenge()-(ger.mitteUnten().y-e.getY());

                                                        if (la8>=15){
                                                            ger.setLaenge(la8);

                                                            if( verY % 2 ==0){
                                                                ger.setPos(ger.getX(), ger.getY()+1);
                                                                repaint();
                                                            }
                                                        }                                            
                                                        break;
                                                    }
                                                    case 2:{
                                                        int la8=ger.getLaenge()-(ger.mitteUnten().y-e.getY());

                                                        if (la8>=20){
                                                            ger.setLaenge(la8);

                                                            if( verY % 2 ==0){
                                                                ger.setPos(ger.getX(), ger.getY()+1);
                                                                repaint();
                                                            }
                                                        }                                            
                                                        break;
                                                    }
                                                    case 3:{
                                                        int la8=ger.getLaenge()-(ger.mitteUnten().y-e.getY());

                                                        if (la8>=15){
                                                            ger.setLaenge(la8);

                                                            if( verY % 2 ==0){
                                                                ger.setPos(ger.getX(), ger.getY()+1);
                                                                repaint();
                                                            }
                                                        }                                            
                                                        break;                                                    
                                                    }
                                                }
                                                break;
                                        }
                                    }
                                    if(Maus==e.getX()&Maus1>e.getY()){
                                        //Maus bewegt sich nach oben

                                        switch(Mauspos){
                                            //links oben
                                            case 1:
                                                int la=ger.getLaenge()+ger.linkerObenEckpunkt().y-e.getY();
                                                if ( la>=50&ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la);
                                                    if(ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                        int be = ((ObjectifiedAssociation)ger).getRauteLaenge()+ger.linkerObenEckpunkt().y-e.getY();

                                                        ((ObjectifiedAssociation)ger).setRauteLaenge(be);
                                                    }
                                                    if(verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()-1);
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX(),ger.getY()-1);
                                                        repaint();
                                                    }
                                                }
                                                if(la>=30&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la);
                                                    if( verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()-1);
                                                    repaint();
                                                    }
                                                }
                                                break;
                                            //rechts oben    
                                            case 2:
                                                int la2=ger.getLaenge()+ger.rechterObenEckpunkt().y-e.getY();                                           
                                                if ( la2>=50&ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la2);
                                                    if(ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                        int be = ((ObjectifiedAssociation)ger).getRauteLaenge()+ger.rechterObenEckpunkt().y-e.getY();

                                                        ((ObjectifiedAssociation)ger).setRauteLaenge(be);
                                                    }
                                                    if(verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()-1);
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX(),ger.getY()-1);
                                                        repaint();
                                                    }
                                                }
                                                if(la2>=30&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la2);
                                                    if( verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()-1);
                                                    repaint();
                                                    }
                                                }
                                                break;
                                            //links unten    
                                            case 3:

                                                int la3=ger.getLaenge()-(ger.linkerUntenEckpunkt().y-e.getY());                                           
                                                if ( la3>=50&ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la3);
                                                    if(ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                        int be = ((ObjectifiedAssociation)ger).getRauteLaenge()-(ger.linkerUntenEckpunkt().y-e.getY());

                                                        ((ObjectifiedAssociation)ger).setRauteLaenge(be);
                                                    }
                                                    if(verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()-1);
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX(),ger.getY()-1);
                                                       repaint();
                                                    }
                                                }                                            
                                                if(la3>=30&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la3);
                                                    if( verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()-1);    
                                                    repaint();
                                                    }
                                                }
                                                break;
                                            //rechts unten
                                            case 4:

                                                int la4=ger.getLaenge()-(ger.rechterUntenEckpunkt().y-e.getY());                                            
                                                if ( la4>=50&ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la4);
                                                    if(ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                        int be = ((ObjectifiedAssociation)ger).getRauteLaenge()-(ger.rechterUntenEckpunkt().y-e.getY());

                                                        ((ObjectifiedAssociation)ger).setRauteLaenge(be);
                                                    }
                                                    if(verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()-1);
                                                        ((ObjectifiedAssociation)ger).getRaute().setPos(ger.getX(),ger.getY()-1);
                                                       repaint();
                                                    }
                                                }
                                                if(la4>=30&!ger.getClass().getSimpleName().equals("RauteRechteck")){
                                                    ger.setLaenge(la4);
                                                    if( verY % 2 ==0){
                                                        ger.setPos(ger.getX(), ger.getY()-1);  
                                                    repaint();
                                                    }
                                                }
                                                break;
                                            case 7:
                                                int iSwitch7 = 0;
                                                if (ger.getClass().getSimpleName().equals("Raute")){
                                                    iSwitch7 = 1;
                                                }else if (ger.getClass().getSimpleName().equals("Kreis")){
                                                    iSwitch7 = 2;
                                                }else if (ger.getClass().getSimpleName().equals("Namenskonvention")){
                                                    iSwitch7 = 3;
                                                }
                                               switch(iSwitch7){
                                                   case 1:{

                                                        int la7=ger.getLaenge()+(ger.mitteOben().y-e.getY());

                                                        if (la7>=15){
                                                            ger.setLaenge(la7);

                                                            if( verY % 2 ==0){
                                                                ger.setPos(ger.getX(), ger.getY()-1);    
                                                                repaint();
                                                            }
                                                        }
                                                        break;
                                                   }
                                                   case 2:{
                                                        int la7=ger.getLaenge()+(ger.mitteOben().y-e.getY());

                                                        if (la7>=20){
                                                            ger.setLaenge(la7);

                                                            if( verY % 2 ==0){
                                                                ger.setPos(ger.getX(), ger.getY()-1);   
                                                                repaint();
                                                            }
                                                        }
                                                        break;                                                   
                                                   }
                                                   case 3:{

                                                        int la7=ger.getLaenge()+(ger.mitteOben().y-e.getY());

                                                        if (la7>=15){
                                                            ger.setLaenge(la7);

                                                            if( verY % 2 ==0){
                                                                ger.setPos(ger.getX(), ger.getY()-1);  
                                                                repaint();
                                                            }
                                                        }
                                                        break;                                                   
                                                   }
                                               }
                                            case 8:
                                                int iSwitch8 = 0;
                                                if (ger.getClass().getSimpleName().equals("Raute")){
                                                    iSwitch8 = 1;
                                                }else if (ger.getClass().getSimpleName().equals("Kreis")){
                                                    iSwitch8 = 2;
                                                }else if (ger.getClass().getSimpleName().equals("Namenskonvention")){
                                                    iSwitch8 = 3;
                                                }
                                               switch(iSwitch8){
                                                   case 1:{


                                                        int la8=ger.getLaenge()-(ger.mitteUnten().y-e.getY());

                                                        if (la8>=15){
                                                            ger.setLaenge(la8);

                                                            if( verY % 2 ==0){
                                                                ger.setPos(ger.getX(), ger.getY()-1);   
                                                                repaint();
                                                            }
                                                        }                                            
                                                        break;
                                                   }
                                                    case 2:{
                                                        int la8=ger.getLaenge()-(ger.mitteUnten().y-e.getY());

                                                         if (la8>=20){
                                                             ger.setLaenge(la8);

                                                             if( verY % 2 ==0){
                                                                 ger.setPos(ger.getX(), ger.getY()-1);   
                                                                 repaint();
                                                             }
                                                         }                                            
                                                    break;                                                   
                                                    }
                                                    case 3:{
                                                        int la8=ger.getLaenge()-(ger.mitteUnten().y-e.getY());

                                                         if (la8>=15){
                                                             ger.setLaenge(la8);

                                                             if( verY % 2 ==0){
                                                                 ger.setPos(ger.getX(), ger.getY()-1);   
                                                                 repaint();
                                                             }
                                                         }                                            
                                                    break;                                                    
                                                    }

                                               }
                                                break;
                                        }
                                    }
                                    Maus=e.getX();//X-Koordinate der Maus merken um veränderung der Maus abzufragen
                                    Maus1=e.getY();//Y-koordinate der Maus merken um Veränderung der Maus abzufragen
                                }
                            } 
                        }   
                    }
                    break;
            case 0:
                if (SwingUtilities.isLeftMouseButton(e)){
                    if (move){
                        // Here you can make Area Smaller as well if you want when you move an Object closer to eachother
                        setArea(e.getX() + D / 2, e.getY() + D / 2);
        // Bewegen von alle Selectierten Objekte?
                        moveZeichenobjekt (pos, e.getX()+deltaX,e.getY()+deltaY); // also moves lines assigned to the ZO
        //               moveZeichenobjekt (listOfZeichenobjekte.get(pos).getId(), e.getX()+deltaX,e.getY()+deltaY); // also moves lines assigned to the ZO
                        repaint();
                    }
                    // move LineObject EP to new loc or move the LineObject von or nach to new Lock with setPointx(int point, int x, int y))
                    if(epMove){
//Problem 1: This here should happen but it doN#t the first time => epMove shoud be SET to TRUE if you draged an EP of Line                        
                        listOfGeraden.get(posGer).setPointx(epNumber, e.getX(),e.getY());
                        repaint();
                    }
                }
                break;
        }
    }
    @Override
    public void mouseMoved(MouseEvent e) {

        for (PolygonObject ger : listOfZeichenobjekte){
            if (ger.isSelected()){
                String Objekt= ger.getClass().getSimpleName();
                
                if (Objekt.equals("Systemtyp")||Objekt.equals("Enumtyp")||Objekt.equals("Basistyp")||Objekt.equals("Rechteck")||Objekt.equals("RauteRechteck")){
                 
                    if (  e.getX()> ger.linkerObenEckpunkt().getX()-2 && e.getX()< ger.linkerObenEckpunkt().getX()+2 && e.getY()>ger.linkerObenEckpunkt().getY()-2&& e.getY()<ger.linkerObenEckpunkt().getY()+2 
                        ||e.getX()> ger.rechterObenEckpunkt().getX()-2 && e.getX()< ger.rechterObenEckpunkt().getX()+2 && e.getY()>ger.rechterObenEckpunkt().getY()-2&& e.getY()<ger.rechterObenEckpunkt().getY()+2 
                        ||e.getX()> ger.linkerUntenEckpunkt().getX()-2 && e.getX()< ger.linkerUntenEckpunkt().getX()+2 && e.getY()>ger.linkerUntenEckpunkt().getY()-2&& e.getY()<ger.linkerUntenEckpunkt().getY()+2
                        ||e.getX()> ger.rechterUntenEckpunkt().getX()-2 && e.getX()< ger.rechterUntenEckpunkt().getX()+2 && e.getY()>ger.rechterUntenEckpunkt().getY()-2&& e.getY()<ger.rechterUntenEckpunkt().getY()+2 )
                        {

                            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                            Hand=1;
                        }
                    else
                        {
                        setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                        Hand=0;
                        }
                }
                if(Objekt.equals("Raute")||Objekt.equals("Kreis")||Objekt.equals("Namenskonvention")){
                    if(e.getX()> ger.mitteLinks().getX()-2 && e.getX()< ger.mitteLinks().getX()+2 && e.getY()>ger.mitteLinks().getY()-2&& e.getY()<ger.mitteLinks().getY()+2 
                    ||e.getX()> ger.mitteRechts().getX()-2 && e.getX()< ger.mitteRechts().getX()+2 && e.getY()>ger.mitteRechts().getY()-2&& e.getY()<ger.mitteRechts().getY()+2 
                    ||e.getX()> ger.mitteOben().getX()-2 && e.getX()< ger.mitteOben().getX()+2 && e.getY()>ger.mitteOben().getY()-2&& e.getY()<ger.mitteOben().getY()+2 
                    ||e.getX()> ger.mitteUnten().getX()-2 && e.getX()< ger.mitteUnten().getX()+2 && e.getY()>ger.mitteUnten().getY()-2&& e.getY()<ger.mitteUnten().getY()+2 )
                    {
                       setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                        Hand=1;
                    }
                    else
                        {
                        setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                        Hand=0;
                        }
                }
                
            }
        }
        if (addingline == true ){
                    listOfGeraden.getLast().setPointx(2, e.getX(),e.getY());
                    repaint();
        }
    }

    /*
     * 14berpr�A14 ft den Darstellungsbereich der Zeichenflaeche und
     * passt diesen an , wenn er groesser als der bisherige Bereich ist.
     * intx Rechte Grenze
     * inty untere Grenze
     * Wir brauchen auch umkehrt ein methode der der Sicht shrinkt bis objekten
     */
    private void setArea(int posx, int posy) {
        
        boolean changed = false;
        int this_width = (posx + D);
        if (this_width > area.width) {
            area.width = this_width;
            changed = true;
        }


        int this_height = (posy + D);
        if (this_height > area.height) {
            area.height = this_height;
            changed = true;
        }

        if (changed) {
            // Update c l i e n t � s prefer red si ze because
            // the area taken up by the graphics has
            // got ten l a r g e r or smaller ( if cleared ) .
            setPreferredSize(area);

            // Let the s c r o l l pane know to update i t s e l f
            // and its s c r o l l b a r s .
            revalidate();
        }
    }
     
     public Point getMousePositions(){
             PointerInfo a = MouseInfo.getPointerInfo();
             return a.getLocation();
     }
     
     public void deselectAll(){
        
        for (PolygonObject ger : listOfZeichenobjekte){
            if(ger.isSelected()) ger.setSelected(false);
        }
        for (LineObject ger : listOfGeraden){
            if(ger.isSelected()) ger.setSelected(false);
        }
     }
 
    public int getIndexOfZeichenobjektInPosition(int x, int y){
        for (PolygonObject ger : listOfZeichenobjekte){
            if(ger.isInArea(x, y)){
                return listOfZeichenobjekte.indexOf(ger);
            }
        }
        return 99999999;
    }
 
   public MouseState getMouseState() {
        return mouseState;
   }
   public void setMouseState(MouseState mouseState) {
        this.mouseState = mouseState;
   }
   
   public void setMouseState(MouseState mouseState, MouseState lineType) {
        this.mouseState = mouseState;
        this.lineType = lineType;
        this.addingline = false; // reset addingLine
   }
   
   public void resetWindow(){
       area.setSize(400,300);
       this.setPreferredSize(area);
       listOfZeichenobjekte = new LinkedList<PolygonObject>();
       listOfGeraden = new LinkedList<LineObject>();
       repaint();
   }
   
   public void moveZeichenobjekt (int index, int x, int y){
       // replace listOfZeichenobjekte.get(pos).move(e.getX()+deltaX,e.getY()+deltaY); 
       listOfZeichenobjekte.get(index).move(x,y);
       
       int indexZoID = listOfZeichenobjekte.get(index).getId();
       
       // look throw GeradeLIst for Geraden connected to that object and move them acordingly 
       
       for (LineObject ger : listOfGeraden){
           if (indexZoID == ger.getVonZOindex()){
               // new kalkulation entsprehend ger.getNachZOindex()
               int [] rec; 
               rec = recalcGeradePositions(ger);
               ger.setPointx(1, rec[0], rec[1]); 
               ger.setPointx(2, rec[2], rec[3]); 
           }else if (indexZoID == ger.getNachZOindex()){ 
               int [] rec; 
               rec = recalcGeradePositions(ger);
               ger.setPointx(1, rec[0], rec[1]); 
               ger.setPointx(2, rec[2], rec[3]); 
           }
       }
       repaint();
   }
   
   public void deleteSelected (){
       for (PolygonObject it : listOfZeichenobjekte){
            if(it.isSelected()){
                // select all the lines connected to the ZO
                for (LineObject ger : listOfGeraden){
                            if( (ger.getVonZOindex() == it.getId()) || (ger.getNachZOindex() == it.getId()) ){
                                ger.setSelected(true);
                            }
                }
            }
       }
       
       for(Iterator<LineObject> it = listOfGeraden.iterator(); it.hasNext(); ) {
            if(it.next().isSelected()) { 
                it.remove(); 
            }
       }

       for(Iterator<PolygonObject> it=listOfZeichenobjekte.iterator(); it.hasNext(); ) {
            if(it.next().isSelected()) { 
                it.remove(); 
            }
       }
       repaint();
    }  
       
    // in 90 Grad positionen endern sich gx nicht und bleiben bei -1, -2 so on
    private int[] recalcGeradePositions(LineObject gerade){
           
                            int vonZOid = gerade.getVonZOindex();
                            int nachZOid = gerade.getNachZOindex();
                            
                            int gx1 = gerade.getVonX() ,gy1 = gerade.getVonY(), gx2 = gerade.getNachX() ,gy2 = gerade.getNachY(); // wir nehmen an wir haben kein Negativen Koordinaten
                            int vonZOindex = 0; // Old = -1
                            int nachZOindex = -1;
                            for (PolygonObject zo : listOfZeichenobjekte){
                                if(vonZOid == zo.getId()){
                                    vonZOindex = listOfZeichenobjekte.indexOf(zo);
//                                    nachZOindex = gerade.getNachZOindex();
                                }
                                if(nachZOid == zo.getId()){
                                    nachZOindex = listOfZeichenobjekte.indexOf(zo);
//                                    vonZOindex = gerade.getVonZOindex();
                                }
                            }
                            
                            // if new Line then they are -1 witch is bad
//                            int vonZOindex = gerade.getVonZOindex();
//                            int nachZOindex = gerade.getNachZOindex();
                            
                            PolygonObject vonZO = listOfZeichenobjekte.get(vonZOindex);
                            PolygonObject nachZO = listOfZeichenobjekte.get(nachZOindex);
                            
                            // richtigen Stellen falls eine der Objekte ObjectifiedAssociation ist

                            if(((vonZO instanceof ObjectifiedAssociation)&& (nachZO instanceof Entity))||
                                 ((listOfZeichenobjekte.get(vonZOindex) instanceof ObjectifiedAssociation)&&(listOfZeichenobjekte.get(nachZOindex)instanceof BaseType))|| 
                                  ((listOfZeichenobjekte.get(vonZOindex) instanceof ObjectifiedAssociation)&&(listOfZeichenobjekte.get(nachZOindex)instanceof SystemType))||
                                  ((listOfZeichenobjekte.get(vonZOindex) instanceof ObjectifiedAssociation)&&(listOfZeichenobjekte.get(nachZOindex)instanceof EnumType))
                                 ) {
                                vonZO = ((ObjectifiedAssociation)vonZO).getRaute();
                            }
                            if(((vonZO instanceof Entity)&& (nachZO instanceof ObjectifiedAssociation))||
                                    ((listOfZeichenobjekte.get(vonZOindex) instanceof BaseType)&&(listOfZeichenobjekte.get(nachZOindex)instanceof ObjectifiedAssociation))||
                                     ((listOfZeichenobjekte.get(vonZOindex) instanceof SystemType)&&(listOfZeichenobjekte.get(nachZOindex)instanceof ObjectifiedAssociation))||
                                    ((listOfZeichenobjekte.get(vonZOindex) instanceof EnumType)&&(listOfZeichenobjekte.get(nachZOindex)instanceof ObjectifiedAssociation))
                                    ){
                                nachZO = ((ObjectifiedAssociation)nachZO).getRaute();
                            }
                            
                            
                            if(vonZO.getX() <= nachZO.getX() &&  vonZO.getY() <= nachZO.getY() ){
                                if(vonZO.getX() - nachZO.getX() <=  vonZO.getY() - nachZO.getY()  ){
                                    // Delda Y ist grosser also wir nehmen der Unteren Andokingspunkt an der ersten Objekt und Oberen and der zweiten
                                    gx1 = vonZO.mitterechts.x + EditPoint.size/2;
                                    gy1 = vonZO.mitterechts.y + EditPoint.size/2;
                                    gx2 = nachZO.mittelinks.x + EditPoint.size/2;
                                    gy2 = nachZO.mittelinks.y + EditPoint.size/2;
                                }else{
                                    // Obj1 - Linke ; Obj2 - Rechte
                                    gx1 = vonZO.untenmitte.x + EditPoint.size/2;
                                    gy1 = vonZO.untenmitte.y + EditPoint.size/2;
                                    gx2 = nachZO.obenmitte.x + EditPoint.size/2;
                                    gy2 = nachZO.obenmitte.y + EditPoint.size/2;
                                }
                            }
                            // Oben Recht
                            if(vonZO.getX() <= nachZO.getX() &&  vonZO.getY() >= nachZO.getY() ){
                                // der zweite Objekt befindet sich  oben rechts ungenau
                                if(vonZO.getX() - nachZO.getX() <=  nachZO.getY() - vonZO.getY()   ){
                                    gx1 = vonZO.mitterechts.x + EditPoint.size/2;
                                    gy1 = vonZO.mitterechts.y + EditPoint.size/2;
                                    gx2 = nachZO.mittelinks.x + EditPoint.size/2;
                                    gy2 = nachZO.mittelinks.y + EditPoint.size/2;
                                }else{
                                    gx1 = vonZO.obenmitte.x + EditPoint.size/2;
                                    gy1 = vonZO.obenmitte.y + EditPoint.size/2;
                                    gx2 = nachZO.untenmitte.x + EditPoint.size/2;
                                    gy2 = nachZO.untenmitte.y + EditPoint.size/2;
                                }
                            }
                            //
                            if(vonZO.getX() >= nachZO.getX() &&  vonZO.getY() <= nachZO.getY() ){
                                // der zweite Objekt befindet sich in unten rechts ungenau ;
                                // Delta berechnene groser kleiner:
                                if(nachZO.getX()- vonZO.getX() <=  vonZO.getY() - nachZO.getY()  ){
                                    // Delda Y ist grosser also wir nehmen der Unteren Andokingspunkt an der ersten Objekt und Oberen and der zweiten
                                    gx1 = vonZO.mittelinks.x + EditPoint.size/2;
                                    gy1 = vonZO.mittelinks.y + EditPoint.size/2;
                                    gx2 = nachZO.mitterechts.x + EditPoint.size/2;
                                    gy2 = nachZO.mitterechts.y + EditPoint.size/2;
                                }else{
                                    // Obj1 - Linke ; Obj2 - Rechte
                                    gx1 = vonZO.untenmitte.x + EditPoint.size/2;
                                    gy1 = vonZO.untenmitte.y + EditPoint.size/2;
                                    gx2 = nachZO.obenmitte.x + EditPoint.size/2;
                                    gy2 = nachZO.obenmitte.y + EditPoint.size/2;
                                }
                            }
                            // 
                            if(vonZO.getX() >= nachZO.getX() &&  vonZO.getY() >= nachZO.getY() ){
                                // der zweite Objekt befindet sich  oben rechts ungenau
                                if(nachZO.getX()-vonZO.getX() <=  nachZO.getY() - vonZO.getY()   ){
                                    gx1 = vonZO.mittelinks.x + EditPoint.size/2;
                                    gy1 = vonZO.mittelinks.y + EditPoint.size/2;
                                    gx2 = nachZO.mitterechts.x + EditPoint.size/2;
                                    gy2 = nachZO.mitterechts.y + EditPoint.size/2;
                                }else{
                                    gx1 = vonZO.obenmitte.x + EditPoint.size/2;
                                    gy1 = vonZO.obenmitte.y + EditPoint.size/2;
                                    gx2 = nachZO.untenmitte.x + EditPoint.size/2;
                                    gy2 = nachZO.untenmitte.y + EditPoint.size/2;
                                }
                            }
                   int [] ret= new int[4]; 
                   ret[0] = gx1; ret[1] = gy1; ret[2] = gx2; ret[3] = gy2;
                   return ret;               
       }


class MousePopupListener extends MouseAdapter {
    
    public void mousePressed(MouseEvent e) {
      checkPopup(e);
    }

    
    public void mouseClicked(MouseEvent e) {
      checkPopup(e);
    }

  
    public void mouseReleased(MouseEvent e) {
      checkPopup(e);
    }

    private void checkPopup(MouseEvent e) {
      if (e.isPopupTrigger()) {
        popup.show(GuiJPanel.this, e.getX(), e.getY());
      }    
    }
  }	      

    public Dimension getArea() {
        return area;
    }

   public void saveFile(File file){
        try {
          // Save Collection object in File
          //textarea.write( new FileWriter( file.getAbsolutePath() ) );  // pls no hardcoded saves :)
          FileOutputStream saveFile = new FileOutputStream(file.getAbsolutePath()); //file.getAbsolutePath() //"D:\\SaveObj.txt"
          String saveString = "";
          for (PolygonObject zo : listOfZeichenobjekte){
              saveString = saveString +zo.getObjectInString() + "\n";
          }
          
          for (LineObject ger : listOfGeraden){
              saveString = saveString + ger.getObjectInString() + "\n";
          }
          
          
          try {

              saveFile.write(

                  (saveString).getBytes("UTF-8") // Choose your encoding.

              );

          } finally {
                  saveFile.close();
          }
        } catch (IOException ex) {
          System.out.println("problem accessing file" +file.getAbsolutePath());
        }
    }

//! Big Problems with the Naming of the Objects and saving of strings
   public void openFile(File file){
        try {
          // will reset even if file could not open
          resetWindow();
          
          BufferedReader reader = new BufferedReader(new FileReader(file.getAbsolutePath()));
            String line = null;
            while ((line = reader.readLine()) != null) {
//                System.out.println(line);
                
                // add the right Objects after an other:
                String objSuperType = line.substring(0, 2); // erste 2 stellen von line
                String objSubTypeTemp = line.substring(3); //entire line for subtype  - we use that later
                String [] objSubTypeArr = objSubTypeTemp.split(";"); // SubType;blqblq...
                String objSubType = objSubTypeArr[0];       //Subtype
                int iSwitch1 = 0;
                if (objSuperType.equals("zo")){
                    iSwitch1 = 1;
                }else if (objSuperType.equals("gr")){
                    iSwitch1 = 2;
                }
//++++++++++++++++++++++++++++++++                
                switch (iSwitch1){
                    case 1:
                        // save the rest of the line String after SubType: objSubTypeArr[0] is the SubType the rest is what we need here
                        //  + x + ";" +  y+ ";" +  id + ";" +  breite + ";" +  laenge + ";" +  name + ";";
                        //    1          2         3              4              5              6
                        int x = Integer.parseInt(objSubTypeArr[1]);
                        int y = Integer.parseInt(objSubTypeArr[2]);
                        int id = Integer.parseInt(objSubTypeArr[3]);
                        int breite = Integer.parseInt(objSubTypeArr[4]);
                        int laenge = Integer.parseInt(objSubTypeArr[5]);
                        String name = "";
                        try {
                            name = objSubTypeArr[6];
                        } catch (ArrayIndexOutOfBoundsException ex) {
                        }
                        
                        PolygonObject newZo;
                        
                        int iSwitch2 = 0;
                        if (objSubType.equals("Rechteck")){
                            iSwitch2 = 1;
                        }else if (objSubType.equals("Systemtyp")){
                            iSwitch2 = 2;
                        }else if (objSubType.equals("RauteRechteck")){
                            iSwitch2 = 3;
                        }else if (objSubType.equals("Raute")){
                            iSwitch2 = 4;
                        }else if (objSubType.equals("Kreis")){
                            iSwitch2 = 5;
                        }else if (objSubType.equals("Enumtyp")){
                            iSwitch2 = 6;
                        }else if (objSubType.equals("Basistyp")){
                            iSwitch2 = 7;
                        }
                        switch (iSwitch2){
                            case 1:
                              newZo = new Entity(x, y, id);
                              newZo.setBreite(breite);
                              newZo.setLaenge(laenge);
                              newZo.umbenennen(name);
                              this.listOfZeichenobjekte.add(newZo);
                              break;
                            case 2:
                              newZo = new SystemType(x, y, id);
                              newZo.setBreite(breite);
                              newZo.setLaenge(laenge);
                              newZo.umbenennen(name);
                              this.listOfZeichenobjekte.add(newZo);
                              break;
                            case 3:
                              newZo = new ObjectifiedAssociation(x, y, id);
                              newZo.setBreite(breite);
                              newZo.setLaenge(laenge);
                              newZo.umbenennen(name);
                              this.listOfZeichenobjekte.add(newZo);
                              break;
                            case 4:
                              newZo = new Association(x, y, id);
                              newZo.setBreite(breite);
                              newZo.setLaenge(laenge);
                              newZo.umbenennen(name);
                              this.listOfZeichenobjekte.add(newZo);
                              break;
                            case 5:
                              newZo = new DerivationNod(x, y, id);
                              newZo.setBreite(breite);
                              newZo.setLaenge(laenge);
                              newZo.umbenennen(name);
                              this.listOfZeichenobjekte.add(newZo);
                              break;
                            case 6:
                              newZo = new EnumType(x, y, id);
                              newZo.setBreite(breite);
                              newZo.setLaenge(laenge);
                              newZo.umbenennen(name);
                              this.listOfZeichenobjekte.add(newZo);
                              break;
                            case 7:
                              newZo = new BaseType(x, y, id);
                              newZo.setBreite(breite);
                              newZo.setLaenge(laenge);
                              newZo.umbenennen(name);
                              this.listOfZeichenobjekte.add(newZo);
                              break;
                        }
                        break;
                    case 2:
                                                                         
                        
                        int vonX = Integer.parseInt(objSubTypeArr[1]);
                        int vonY = Integer.parseInt(objSubTypeArr[2]);
                        int nachX = Integer.parseInt(objSubTypeArr[3]);
                        int nachY = Integer.parseInt(objSubTypeArr[4]);
                        int vonZOindex = Integer.parseInt(objSubTypeArr[5]);
                        int nachZOindex = Integer.parseInt(objSubTypeArr[6]);

                        String nameG = "";
                        try {
                            nameG = objSubTypeArr[7];
                        } catch (ArrayIndexOutOfBoundsException ex) {
                        }
                        
                        String relation = "";
                        try {
                            nameG = objSubTypeArr[8];
                        } catch (ArrayIndexOutOfBoundsException ex) {
                        }
                        
                        LineObject newGr; // (int vonX, int vonY, int nachX, int nachY)
                        int [] rec;
                        int iSwitch3 = 0;
                        if (objSubType.equals("Pfeil")){
                            iSwitch3 = 1;
                        }else if (objSubType.equals("GeschtrichelterPfeil")){
                            iSwitch3 = 2;
                        }else if (objSubType.equals("Linie")){
                            iSwitch3 = 3;
                        }
                        switch (iSwitch3){
                            case 1:
                                newGr = new Generalization(vonX, vonY, nachX, nachY );
                                newGr.setVonZOindex(vonZOindex);
                                newGr.setNachZOindex(nachZOindex);
                                rec = recalcGeradePositions(newGr);
                                newGr.setPointx(1, rec[0], rec[1]); 
                                newGr.setPointx(2, rec[2], rec[3]);
                                this.listOfGeraden.add(newGr);
                                break;
                            case 2:
                                newGr = new RepresentedBy(vonX, vonY, nachX, nachY );
                                newGr.setVonZOindex(vonZOindex);
                                newGr.setNachZOindex(nachZOindex);
                                rec = recalcGeradePositions(newGr);
                                newGr.setPointx(1, rec[0], rec[1]); 
                                newGr.setPointx(2, rec[2], rec[3]);
                                this.listOfGeraden.add(newGr);
                                break;
                            case 3:
                                newGr = new Relationship(vonX, vonY, nachX, nachY );
                                newGr.setVonZOindex(vonZOindex);
                                newGr.setNachZOindex(nachZOindex);
                                rec = recalcGeradePositions(newGr);
                                newGr.setPointx(1, rec[0], rec[1]); 
                                newGr.setPointx(2, rec[2], rec[3]);
                                
                                newGr.setName(nameG);
                                newGr.setRelation(relation);
                                
                                this.listOfGeraden.add(newGr);
                                break;
                            
                        }
                        break;
                }
            }
          
        } catch (IOException ex) {
          System.out.println("problem accessing file" +file.getAbsolutePath());
        }
   }  
   
 
  public void dbSave(){
        String name = "";
         String pass = "";
        name = JOptionPane.showInputDialog("name", name);
        if  (name==(null)){
            JOptionPane.showMessageDialog(null,"Vorgang abgebrochen!");
            return;
            }//abfangen falls kein Name eingegeben wird
        else  
        if (name.length()==0){
            JOptionPane.showMessageDialog(null,"Keinen Wert eingegben!");  
            return;
            }
       
        pass = JOptionPane.showInputDialog("pass", pass);
        if  (pass==(null)){
            JOptionPane.showMessageDialog(null,"Vorgang abgebrochen!");
            return;
            }//abfangen falls kein Name eingegeben wird
        else  
        if (pass.length()==0){
            JOptionPane.showMessageDialog(null,"Keinen Wert eingegben!");
            return;
            }
        
        if (isAgilaUser(name,pass)){
            saveDBtxt();
        }
    
      
      
      
  }
  
  public boolean isAgilaUser(String user, String pass){
      int test = -1;
      try {
                    //jdbc Treiber laden
                    Class.forName("oracle.jdbc.driver.OracleDriver");
                    System.out.println("JDBC-Driver loaded");
               } 
                catch (ClassNotFoundException e) {
                        System.out.println("JDBC-Driver could not be loaded");
                        e.printStackTrace();
                }


            // Start Connection to Database
            try {
                    //Aufbau der Connection 
                    //Form des Strings = jdbc:oracle:thin:<Benutzername>/<PWD>@<Host>:<Port>:<SID>
                    //HOST = agila.informatik.fh-augsburg.de
                    //Port = 1521
                    //SID = o11a4
                    //Benutzername = agila 
                    //pwd = test123
                    Connection con = DriverManager.getConnection("jdbc:oracle:thin:agilaweb/geheim@agila.informatik.fh-augsburg.de:1521:o11a4");
                    System.out.println("Conntected to Database");
                    Statement stmt = con.createStatement();

                    //Statements select auf GEO aus der AGILA DB
                    CallableStatement callableStatement = con.prepareCall("{ ? = call ddlog$ (?,?)}");
                    callableStatement.registerOutParameter(1, Types.INTEGER);
                    callableStatement.setString(2, user);
                    callableStatement.setString(3, pass);
                    
                    callableStatement.execute();
                    test= callableStatement.getInt(1);
                    System.out.println(test);     
            } 
            catch (SQLException e) {
                    System.out.println("Connection to Database failed");
                    e.printStackTrace();
            }
            return (test == 0);
  }
  
  // speichern in der DB
  public void saveDBtxt(){
      
  }
}//end class GUI  

